package com.yangmf.auto_message_handle.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.yangmf.auto_message_handle.pojo.entity.StorageInfo;
import com.yangmf.auto_message_handle.properties.AliOssProperties;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.util.List;

@Data
@NoArgsConstructor
@Slf4j
@Component
public class AliOssUtil {

    @Autowired
    private AliOssProperties properties;

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    @PostConstruct
    public void init() {
        if (properties != null) {
            this.endpoint = properties.getEndpoint();
            this.accessKeyId = properties.getAccessKeyId();
            this.accessKeySecret = properties.getAccessKeySecret();
            this.bucketName = properties.getBucketName();

            // 其他初始化逻辑
        }
    }

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }

    /**
     * 获取OSS存储桶中的文件总数
     *
     * @return 文件总数，如果出现异常返回-1
     */
    public long getTotalFileCount() {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        long totalCount = 0;

        try {
            String nextMarker = null;
            ObjectListing objectListing;

            do {
                // 创建列出对象的请求
                ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
                listObjectsRequest.setMarker(nextMarker);
                // 设置每页最多返回1000个对象
                listObjectsRequest.setMaxKeys(1000);

                objectListing = ossClient.listObjects(listObjectsRequest);
                List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
                
                totalCount += sums.size();
                nextMarker = objectListing.getNextMarker();

            } while (objectListing.isTruncated());

            log.info("OSS存储桶 {} 中的文件总数为: {}", bucketName, totalCount);
            return totalCount;

        } catch (OSSException oe) {
            log.error("OSS异常 - Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}", 
                    oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
            return -1;
        } catch (ClientException ce) {
            log.error("客户端异常 - Error Message: {}", ce.getMessage());
            return -1;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 获取OSS存储桶中所有文件的总大小（字节数）
     *
     * @return 文件总大小（字节），如果出现异常返回-1
     */
    public long getTotalFileSize() {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        long totalSize = 0;

        try {
            String nextMarker = null;
            ObjectListing objectListing;

            do {
                // 创建列出对象的请求
                ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
                listObjectsRequest.setMarker(nextMarker);
                // 设置每页最多返回1000个对象
                listObjectsRequest.setMaxKeys(1000);

                objectListing = ossClient.listObjects(listObjectsRequest);
                List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
                
                // 累加所有文件的大小
                for (OSSObjectSummary s : sums) {
                    totalSize += s.getSize();
                }
                
                nextMarker = objectListing.getNextMarker();

            } while (objectListing.isTruncated());

            log.info("OSS存储桶 {} 中的文件总大小为: {} 字节 (约 {} MB)", 
                    bucketName, totalSize, String.format("%.2f", totalSize / (1024.0 * 1024.0)));
            return totalSize;

        } catch (OSSException oe) {
            log.error("OSS异常 - Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}", 
                    oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
            return -1;
        } catch (ClientException ce) {
            log.error("客户端异常 - Error Message: {}", ce.getMessage());
            return -1;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 获取OSS存储桶的存储信息（文件数和总大小）
     *
     * @return StorageInfo 包含文件数和总大小的对象
     */
    public StorageInfo getStorageInfo() {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        long totalCount = 0;
        long totalSize = 0;

        try {
            String nextMarker = null;
            ObjectListing objectListing;

            do {
                // 创建列出对象的请求
                ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
                listObjectsRequest.setMarker(nextMarker);
                // 设置每页最多返回1000个对象
                listObjectsRequest.setMaxKeys(1000);

                objectListing = ossClient.listObjects(listObjectsRequest);
                List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
                
                totalCount += sums.size();
                for (OSSObjectSummary s : sums) {
                    totalSize += s.getSize();
                }
                
                nextMarker = objectListing.getNextMarker();

            } while (objectListing.isTruncated());

            StorageInfo storageInfo = new StorageInfo(totalCount, totalSize);
            log.info("OSS存储桶 {} 的存储信息: 文件数={}, 总大小={} 字节 (约 {} MB)", 
                    bucketName, totalCount, totalSize, String.format("%.2f", totalSize / (1024.0 * 1024.0)));
            
            return storageInfo;

        } catch (OSSException oe) {
            log.error("OSS异常 - Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}", 
                    oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
            return new StorageInfo(-1, -1);
        } catch (ClientException ce) {
            log.error("客户端异常 - Error Message: {}", ce.getMessage());
            return new StorageInfo(-1, -1);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
    /**
     * 删除OSS存储桶中的指定文件
     *
     * @param objectName 要删除的文件名（包含路径）
     * @return 删除成功返回true，失败返回false
     */
    public boolean deleteFile(String objectName) {
        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 检查文件是否存在
            boolean exists = ossClient.doesObjectExist(bucketName, objectName);
            if (!exists) {
                log.warn("文件 {} 在OSS存储桶 {} 中不存在", objectName, bucketName);
                return false;
            }

            // 删除文件
            ossClient.deleteObject(bucketName, objectName);
            log.info("成功删除OSS存储桶 {} 中的文件: {}", bucketName, objectName);
            return true;

        } catch (OSSException oe) {
            log.error("OSS异常 - Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}",
                    oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
            return false;
        } catch (ClientException ce) {
            log.error("客户端异常 - Error Message: {}", ce.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 批量删除OSS存储桶中的多个文件
     *
     * @param objectNames 要删除的文件名列表（包含路径）
     * @return 删除成功的文件数量，如果出现异常返回-1
     */

}